<template>
	<view class="form-create">
		<wd-card>
			<!-- {{ localRule }} -->
			<wd-form ref="formRef" :model="modelValue" :rules="formRules">
				<wd-cell-group border v-for="item in localRule" :key="item.field">
					<view class="">
						<!-- 密码输入框 -->
						<wd-input v-if="item.type === 'input' && item.props?.type === 'password'" :label="item.title"
							:label-width="item?.wrap?.labelWidth || '100px'" :prop="item.field"
							v-model="modelValue[item.field]" :clearable="item.props?.clearable ?? true"
							:placeholder="item.props?.placeholder || ('请输入' + item.title)"
							:disabled="item.props?.disabled ?? false" :readonly="item.props?.readonly ?? false"
							type="password" />

						<!-- 多行输入框 -->
						<wd-textarea v-else-if="item.type === 'input' && item.props?.type === 'textarea'"
							:label="item.title" :label-width="item?.wrap?.labelWidth || '100px'" :prop="item.field"
							v-model="modelValue[item.field]"
							:placeholder="item.props?.placeholder || ('请输入' + item.title)"
							:disabled="item.props?.disabled ?? false" :readonly="item.props?.readonly ?? false"
							:rows="item.props?.rows || 3" :maxlength="item.props?.maxlength" />

						<!-- 单行输入框 -->
						<wd-input v-else-if="item.type === 'input'" :label="item.title"
							:label-width="item?.wrap?.labelWidth || '100px'" :prop="item.field"
							v-model="modelValue[item.field]" :clearable="item.props?.clearable ?? true"
							:placeholder="item.props?.placeholder || ('请输入' + item.title)"
							:disabled="item.props?.disabled ?? false" :readonly="item.props?.readonly ?? false"
							type="text" />

						<!-- 数字输入框 -->
						<wd-cell v-else-if="item.type === 'inputNumber'" :title="item.title"
							:title-width="item?.wrap?.labelWidth || '100px'" :prop="item.field">
							<wd-input-number :label="item.title" :label-width="item?.wrap?.labelWidth || '100px'"
								:prop="item.field" v-model="modelValue[item.field]" :min="item.props?.min ?? 0"
								:max="item.props?.max ?? 999999" :step="item.props?.step ?? 1"
								:disabled="item.props?.disabled ?? false" :readonly="item.props?.readonly ?? false" />
						</wd-cell>

						<!-- 单选框 -->
						<wd-cell v-else-if="item.type === 'radio'" :title="item.title"
							:title-width="item?.wrap?.labelWidth || '100px'" :prop="item.field">
							<wd-radio-group v-model="modelValue[item.field]" :disabled="item.props?.disabled ?? false"
								:readonly="item.props?.readonly ?? false" direction="horizontal">
								<wd-radio
									v-for="opt in (typeof item.options === 'function' ? item.options() : item.options)"
									:key="opt.value" :label="opt.value">
									{{ opt.label }}
								</wd-radio>
							</wd-radio-group>

						</wd-cell>


						<!-- 多选框 -->
						<wd-cell v-else-if="item.type === 'checkbox'" :title="item.title"
							:title-width="item?.wrap?.labelWidth || '100px'" :prop="item.field">

							<wd-checkbox-group v-model="modelValue[item.field]"
								:disabled="item.props?.disabled ?? false" :readonly="item.props?.readonly ?? false"
								direction="horizontal">
								<wd-checkbox
									v-for="opt in (typeof item.options === 'function' ? item.options() : item.options)"
									:key="opt.value" :label="opt.value">
									{{ opt.label }}
								</wd-checkbox>
							</wd-checkbox-group>
						</wd-cell>


						<!-- 下拉选择 -->
						<wd-select-picker v-if="item.type === 'select' && !item.hidden" :label="item.title"
							:label-width="item?.wrap?.labelWidth || '100px'" :prop="item.field"
							v-model="modelValue[item.field]"
							:columns="(typeof item.options === 'function' ? item.options() : item.options)"
							:placeholder="item.props?.placeholder || ('请输入' + item.title)"
							:clearable="item.props?.clearable ?? true" :filterable="item.props?.filterable ?? true"
							:multiple="item.props?.multiple ?? false"
							:type="item.props?.multiple ? 'checkbox' : 'radio'" :show-confirm="false" value-key="value"
							label-key="label" :disabled="item.props?.disabled ?? false"
							:readonly="item.props?.readonly ?? false"></wd-select-picker>

						<!-- 用户选择器 -->
						<wd-select-picker v-if="item.type === 'UserSelect' && !item.hidden" :label="item.title"
							:label-width="item?.wrap?.labelWidth || '100px'" :prop="item.field"
							v-model="modelValue[item.field]" :columns="userOptions"
							:placeholder="item.props?.placeholder || ('请输入' + item.title)"
							:clearable="item.props?.clearable ?? true" :filterable="item.props?.filterable ?? true"
							:multiple="item.props?.multiple ?? false"
							:type="item.props?.multiple ? 'checkbox' : 'radio'" :show-confirm="false" value-key="id"
							label-key="nickname" :disabled="item.props?.disabled ?? false"
							:readonly="item.props?.readonly ?? false"></wd-select-picker>

						<!-- 接口选择器 -->
						<wd-select-picker v-if="item.type === 'ApiSelect' && !item.hidden" :label="item.title"
							:label-width="item?.wrap?.labelWidth || '100px'" :prop="item.field"
							v-model="modelValue[item.field]" :columns="apiColumns[item.field] || []"
							:placeholder="item.props?.placeholder || ('请输入' + item.title)"
							:clearable="item.props?.clearable ?? true" :filterable="item.props?.filterable ?? true"
							:multiple="item.props?.multiple ?? false"
							:type="item.props?.multiple ? 'checkbox' : 'radio'" :show-confirm="false"
							:value-key="item.props?.valueField || 'value'"
							:label-key="item.props?.labelField || 'label'" :disabled="item.props?.disabled ?? false"
							:readonly="item.props?.readonly ?? false"
							@change="(val: any) => handleApiSelectChange(item, val)"></wd-select-picker>

						<!-- 开关 -->
						<wd-cell v-else-if="item.type === 'switch'" :title="item.title"
							:title-width="item?.wrap?.labelWidth || '100px'" :prop="item.field">
							<wd-switch v-model="modelValue[item.field]" :clearable="item.props?.clearable ?? true"
								active-value="1" inactive-value="0"
								:placeholder="item.props?.placeholder || ('请输入' + item.title)"
								:disabled="item.props?.disabled ?? false" :readonly="item.props?.readonly ?? false" />
						</wd-cell>

						<!-- 评分 -->
						<wd-cell v-else-if="item.type === 'rate'" :title="item.title"
							:title-width="item?.wrap?.labelWidth || '100px'" :prop="item.field">
							<wd-rate v-model="modelValue[item.field]" :prop="item.field"
								:disabled="item.props?.disabled ?? false" :readonly="item.props?.readonly ?? false" />
						</wd-cell>

						<!-- 滑块 -->
						<wd-cell v-else-if="item.type === 'slider'" :title="item.title"
							:title-width="item?.wrap?.labelWidth || '100px'" :prop="item.field">
							<wd-slider v-model="modelValue[item.field]" :min="item.props?.min ?? 0"
								:max="item.props?.max ?? 100" :step="item.props?.step ?? 1"
								:disabled="item.props?.disabled ?? false" :readonly="item.props?.readonly ?? false" />
						</wd-cell>


						<!-- 日期选择 -->
						<wd-datetime-picker v-else-if="item.type === 'datePicker'" v-model="modelValue[item.field]"
							:label="item.title" :label-width="item?.wrap?.labelWidth || '100px'" :prop="item.field"
							:type="item.props?.type || 'date'" :placeholder="item.props?.placeholder || '请选择日期'"
							:disabled="item.props?.disabled ?? false" :readonly="item.props?.readonly ?? false"
							:default-value="defaulTimetValue" @confirm="(val: any) => handleDateConfirm(item, val)" />

						<!-- 时间选择 -->
						<wd-datetime-picker v-else-if="item.type === 'timePicker'" v-model="modelValue[item.field]"
							:label="item.title" :label-width="item?.wrap?.labelWidth || '100px'" :prop="item.field"
							:type="item.props?.type || 'datetime'" :is-range="item.props?.isRange ?? false"
							:placeholder="item.props?.placeholder || '请选择时间'" :disabled="item.props?.disabled ?? false"
							:readonly="item.props?.readonly ?? false" :default-value="defaulTimetValue"
							@confirm="(val: any) => handleDateConfirm(item, val)" />



						<!-- upload 文本上传 -->
						<wd-cell v-else-if="item.type === 'UploadFile'" :title="item.title || '文件上传'"
							title-width="100px" :prop="item.field">
							<wd-upload v-model:file-list="fileLists[item.prop]" :action="globalConfig.uploadUrl"
								:limit="item.props?.limit ?? 1" accept="file" :header="headerObj"
								:disabled="item.props?.disabled ?? false"
								@success="(response: any) => handleUploadSuccess(item, response)" />
						</wd-cell>

						<!-- upload 单图片上传 -->
						<wd-cell v-else-if="item.type === 'UploadImg'" :title="item.title || '单图片上传'"
							title-width="100px" :prop="item.field">
							<wd-upload v-model:file-list="fileLists[item.prop]" :action="globalConfig.uploadUrl"
								limit="1" accept="image" :header="headerObj" :disabled="item.props?.disabled ?? false"
								@success="(response: any) => handleUploadSuccess(item, response)" />
						</wd-cell>

						<!-- upload 多图片上传 -->
						<wd-cell v-else-if="item.type === 'UploadImgs'" :title="item.title || '多图片上传'"
							title-width="100px" :prop="item.field">
							<wd-upload v-model:file-list="fileLists[item.prop]" :action="globalConfig.uploadUrl"
								:limit="item.props?.limit" accept="image" :header="headerObj"
								:disabled="item.props?.disabled ?? false"
								@success="(response: any) => handleUploadSuccess(item, response)" />
						</wd-cell>

					</view>
				</wd-cell-group>
			</wd-form>
		</wd-card>

	</view>
</template>

<script lang="ts" setup>
import {
	onLoad, onShow
} from "@dcloudio/uni-app";
import { ref, watch, defineExpose, onMounted, reactive } from 'vue'
import * as UserApi from '@/api/system/user'
import request from '@/utils/request'
import { getAccessToken } from '@/utils/auth'
import { useMessage, useToast } from 'wot-design-uni'
import dayjs from 'dayjs'


const message = useMessage()
const toast = useToast()
interface RuleItem {
	type: string
	field: string
	title: string
	$required?: boolean | string
	options?: any[]
	props?: Record<string, any>
	[key: string]: any
}

interface Option {
	form?: {
		labelWidth?: string
		labelPosition?: 'left' | 'right' | 'top'
		labelSuffix?: string
		[key: string]: any
	}
	submitBtn?: { show: boolean; innerText?: string }
	resetBtn?: { show: boolean; innerText?: string }
}

const props = defineProps<{
	modelValue: Record<string, any>
	api?: any
	option: Option
	rule: RuleItem[]
	disabled?: boolean // 👈 接收 disabled 属性
}>()
const localRule = ref<RuleItem[]>([])
// let localRule = reactive([...props.rule]);
const emit = defineEmits(['update:modelValue', 'update:api'])

const formRef = ref()
const formRules = ref<any>({})
defineExpose({ formRef })

const globalConfig = (getApp() as any).globalData.config;
const headerObj = ref({ Authorization: 'Bearer ' + getAccessToken() })
/**日期选择器默认值 */
const defaulTimetValue = ref<number>(dayjs().startOf('day').valueOf())

const fileLists = reactive<Record<string, any[]>>({})
// 存储所有 ApiSelect 的列数据
const apiColumns = reactive<Record<string, any[]>>({})

//时间选择器时间戳转字符串
const handleDateConfirm = (item: RuleItem, val: any) => {
	if (!val) return
	console.log('val', val);

	// 根据类型选择格式
	const format = item.props?.type === 'datetime' ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD'
	props.modelValue[item.field] = dayjs(val?.value).format(format)
}
// 统一的上传成功处理
const handleUploadSuccess = (item: any, response: any) => {
	console.log('item', item);
	console.log('response', response);

	try {
		console.log('response', response);
		const parsedResponse = JSON.parse(response.file.response)
		const fileUrl = parsedResponse.data // 后端返回的url（字符串）
		const fileName = response.file.name.split('.').slice(0, -1).join('.')
		// 更新目标字段

		if (item.type === 'UploadImgs' || item.props.limit > 1) {
			if (!Array.isArray(props.modelValue[item.field])) {
				props.modelValue[item.field] = []
			}
			props.modelValue[item.field].push(fileUrl)
		} else {
			// 👉 如果是单文件，直接赋值字符串
			props.modelValue[item.field] = fileUrl
		}
		console.log('props.modelValue[item.field]', props.modelValue[item.field]);

		// 更新文件名字段
		// if (item.targetMapping.fileName) {
		// 	const targetKey = item.targetMapping.fileName
		// 	if (item.isMultipleArray) {
		// 		if (!Array.isArray(props.formData[targetKey])) {
		// 			props.formData[targetKey] = []
		// 		}
		// 		props.formData[targetKey].push(fileName)
		// 	} else {
		// 		// 👉 如果是单文件，直接赋值字符串
		// 		props.formData[targetKey] = fileName
		// 	}
		// }
		// if (item.targetMapping.fileName) {

		// 	const targetKey = item.targetMapping.fileName
		// 	props.formData[targetKey] = fileName
		// }

		toast.success('文件上传成功')
	} catch (error) {
		console.error('文件上传结果解析失败', error)
		toast.error('文件解析失败，请检查格式')
	}
}
const handleApiSelectChange = (item: RuleItem, val: any) => {
	// 如果没有配置联动，直接 return，不做额外处理
	if (!item.props?.linkageField || !item.props?.linkageProperty) {
		return
	}

	// ApiSelect 的 columns
	const options = apiColumns[item.field] || []
	console.log('options', options);

	// 找到被选中的完整对象
	const selected = options.find(opt => opt[item.props?.valueField || 'value'] === val.value)
	console.log('selected选中项', selected);

	if (selected && item.props?.linkageField && item.props?.linkageProperty) {
		// 把选中对象里的 linkageProperty 值写到 modelValue[linkageField]
		props.modelValue[item.props.linkageField] = selected[item.props.linkageProperty]
		console.log(
			`联动：${item.field} -> ${item.props.linkageField} = ${selected[item.props.linkageProperty]}`
		)
	}
}

const initApiSelectColumns = async (rules: RuleItem[]) => {
	console.log('执行了吗');

	for (const item of rules) {
		if (item.type === 'ApiSelect' && item.props?.url) {
			try {
				const res = await request.get({ url: item.props.url })
				apiColumns[item.field] = res.map((d: any) => ({
					value: d[item.props?.valueField || 'value'], // 可选链 + 默认值
					label: d[item.props?.labelField || 'label'],
					...d,
				}))
				console.log('apiColumns', apiColumns)
			} catch (error) {
				console.error('ApiSelect 请求失败', error)
				apiColumns[item.field] = []
			}
		}
	}
}
// 初始化 fileLists，每个 Upload 组件都有一个数组
const initFileLists = (rules: RuleItem[]) => {
	console.log('初始化 fileLists');
	rules.forEach(item => {
		if (['UploadFile', 'UploadImg', 'UploadImgs'].includes(item.type)) {
			// 初始化空数组
			if (!fileLists[item.prop]) {
				fileLists[item.prop] = []
			}

			// 如果 modelValue 已经有值，映射到 fileLists
			const existingValue = props.modelValue[item.field]
			console.log('props.modelValue', props.modelValue);
			console.log('item', item);

			console.log('existingValue', existingValue);

			if (existingValue) {
				if (Array.isArray(existingValue)) {
					// 多文件
					fileLists[item.prop] = existingValue.map((url: string, index: number) => ({
						name: url.split('/').pop() || `file-${index}`,
						url
					}))
				} else if (typeof existingValue === 'string') {
					// 单文件
					fileLists[item.prop] = [{
						name: existingValue.split('/').pop() || 'file',
						url: existingValue
					}]
				}
			}
		}
	})
}

const generateRules = (rules: RuleItem[]) => {
	console.log('ruleshiohoihoi', rules);

	const formRules: Record<string, any[]> = {}
	rules.forEach((item) => {
		if (item.$required) {
			formRules[item.field] = [
				{
					required: true,
					message: typeof item.$required === 'string' ? item.$required : `请输入${item.title}`,
					trigger: 'blur',
				},
			]
		}

	})
	console.log('formRules', formRules);

	return formRules
}
watch(
	() => props.rule,
	(val) => {
		localRule.value = Array.isArray(val) ? [...val] : []
		console.log('localRule.value', localRule.value);

		initFileLists(localRule.value)
		initApiSelectColumns(localRule.value)
		formRules.value = generateRules(localRule.value)
		console.log('formRules', formRules.value);


	},
	{ immediate: true, deep: true }
)
watch(
	() => props.modelValue,
	(val) => {
		console.log('val', val);
		console.log('rule', props.rule);
		emit('update:modelValue', val)
	},
	{ deep: true, immediate: true, }
)

watch(
	() => formRef.value, // 监听组件实例是否就绪
	(newFormRef) => {
		if (newFormRef) {
			console.log('newFormRef', newFormRef);

			emit('update:api', newFormRef) // 传递正确的组件引用
		}
	},
	{ immediate: true }
)
// 监听 modelValue 中有 control 字段的字段变化
const watchedFields = ref<string[]>([]);


/** 初始化 */
const userOptions = ref<UserApi.UserVO[]>([]) // 用户列表

onMounted(async () => {
	// 获得用户列表
	userOptions.value = await UserApi.getSimpleUserList()
	// setupWatchers()

});

</script>

<style scoped>
.form-create {
	padding: 8rpx 2rpx;
	background-color: #fcfcfc;
}
</style>